//Tencent is pleased to support the open source community by making FeatherCNN available.

//Copyright (C) 2018 THL A29 Limited, a Tencent company. All rights reserved.

//Licensed under the BSD 3-Clause License (the "License"); you may not use this file except 
//in compliance with the License. You may obtain a copy of the License at
//
//https://opensource.org/licenses/BSD-3-Clause
//
//Unless required by applicable law or agreed to in writing, software distributed 
//under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
//CONDITIONS OF ANY KIND, either express or implied. See the License for the 
//specific language governing permissions and limitations under the License.


// automatically generated by the FlatBuffers compiler, do not modify


#ifndef FLATBUFFERS_GENERATED_FEATHERSIMPLE_FEATHER_H_
#define FLATBUFFERS_GENERATED_FEATHERSIMPLE_FEATHER_H_

#include "flatbuffers/flatbuffers.h"

namespace feather {

struct NetParameter;

struct InputParameter;

struct LayerParameter;

struct ArgMaxParameter;

struct ConcatParameter;

struct BatchNormParameter;

struct BiasParameter;

struct ConvolutionParameter;

struct CropParameter;

struct DataParameter;

struct DropoutParameter;

struct EltwiseParameter;

struct ELUParameter;

struct EmbedParameter;

struct ExpParameter;

struct FlattenParameter;

struct ImageDataParameter;

struct InnerProductParameter;

struct LogParameter;

struct LRNParameter;

struct PoolingParameter;

struct PowerParameter;

struct PReLUParameter;

struct RecurrentParameter;

struct ReductionParameter;

struct ReLUParameter;

struct ReshapeParameter;

struct TanHParameter;

struct ScaleParameter;

struct SigmoidParameter;

struct SliceParameter;

struct SoftmaxParameter;

struct BlobShape;

struct BlobProto;

namespace EltwiseParameter_ {

enum EltwiseOp {
  EltwiseOp_PROD = 0,
  EltwiseOp_SUM = 1,
  EltwiseOp_MAX_ = 2,
  EltwiseOp_MIN = EltwiseOp_PROD,
  EltwiseOp_MAX = EltwiseOp_MAX_
};

inline EltwiseOp (&EnumValuesEltwiseOp())[3] {
  static EltwiseOp values[] = {
    EltwiseOp_PROD,
    EltwiseOp_SUM,
    EltwiseOp_MAX_
  };
  return values;
}

inline const char **EnumNamesEltwiseOp() {
  static const char *names[] = {
    "PROD",
    "SUM",
    "MAX_",
    nullptr
  };
  return names;
}

inline const char *EnumNameEltwiseOp(EltwiseOp e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesEltwiseOp()[index];
}

}  // namespace EltwiseParameter_

namespace ParamSpec_ {

enum DimCheckMode {
  DimCheckMode_STRICT = 0,
  DimCheckMode_PERMISSIVE = 1,
  DimCheckMode_MIN = DimCheckMode_STRICT,
  DimCheckMode_MAX = DimCheckMode_PERMISSIVE
};

inline DimCheckMode (&EnumValuesDimCheckMode())[2] {
  static DimCheckMode values[] = {
    DimCheckMode_STRICT,
    DimCheckMode_PERMISSIVE
  };
  return values;
}

inline const char **EnumNamesDimCheckMode() {
  static const char *names[] = {
    "STRICT",
    "PERMISSIVE",
    nullptr
  };
  return names;
}

inline const char *EnumNameDimCheckMode(DimCheckMode e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesDimCheckMode()[index];
}

}  // namespace ParamSpec_

namespace LRNParameter_ {

enum NormRegion {
  NormRegion_ACROSS_CHANNELS = 0,
  NormRegion_WITHIN_CHANNEL = 1,
  NormRegion_MIN = NormRegion_ACROSS_CHANNELS,
  NormRegion_MAX = NormRegion_WITHIN_CHANNEL
};

inline NormRegion (&EnumValuesNormRegion())[2] {
  static NormRegion values[] = {
    NormRegion_ACROSS_CHANNELS,
    NormRegion_WITHIN_CHANNEL
  };
  return values;
}

inline const char **EnumNamesNormRegion() {
  static const char *names[] = {
    "ACROSS_CHANNELS",
    "WITHIN_CHANNEL",
    nullptr
  };
  return names;
}

inline const char *EnumNameNormRegion(NormRegion e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesNormRegion()[index];
}

}  // namespace LRNParameter_

namespace PoolingParameter_ {

enum PoolMethod {
  PoolMethod_MAX_ = 0,
  PoolMethod_AVE = 1,
  PoolMethod_STOCHASTIC = 2,
  PoolMethod_MIN = PoolMethod_MAX_,
  PoolMethod_MAX = PoolMethod_STOCHASTIC
};

inline PoolMethod (&EnumValuesPoolMethod())[3] {
  static PoolMethod values[] = {
    PoolMethod_MAX_,
    PoolMethod_AVE,
    PoolMethod_STOCHASTIC
  };
  return values;
}

inline const char **EnumNamesPoolMethod() {
  static const char *names[] = {
    "MAX_",
    "AVE",
    "STOCHASTIC",
    nullptr
  };
  return names;
}

inline const char *EnumNamePoolMethod(PoolMethod e) {
  const size_t index = static_cast<int>(e);
  return EnumNamesPoolMethod()[index];
}

}  // namespace PoolingParameter_

namespace ReductionParameter_ {

enum ReductionOp {
  ReductionOp_SUM = 1,
  ReductionOp_ASUM = 2,
  ReductionOp_SUMSQ = 3,
  ReductionOp_MEAN = 4,
  ReductionOp_MIN = ReductionOp_SUM,
  ReductionOp_MAX = ReductionOp_MEAN
};

inline ReductionOp (&EnumValuesReductionOp())[4] {
  static ReductionOp values[] = {
    ReductionOp_SUM,
    ReductionOp_ASUM,
    ReductionOp_SUMSQ,
    ReductionOp_MEAN
  };
  return values;
}

inline const char **EnumNamesReductionOp() {
  static const char *names[] = {
    "SUM",
    "ASUM",
    "SUMSQ",
    "MEAN",
    nullptr
  };
  return names;
}

inline const char *EnumNameReductionOp(ReductionOp e) {
  const size_t index = static_cast<int>(e) - static_cast<int>(ReductionOp_SUM);
  return EnumNamesReductionOp()[index];
}

}  // namespace ReductionParameter_

struct NetParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NAME = 4,
    VT_INPUT = 6,
    VT_INPUT_SHAPE = 8,
    VT_LAYER = 10
  };
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *input() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_INPUT);
  }
  const flatbuffers::Vector<flatbuffers::Offset<BlobShape>> *input_shape() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<BlobShape>> *>(VT_INPUT_SHAPE);
  }
  const flatbuffers::Vector<flatbuffers::Offset<LayerParameter>> *layer() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<LayerParameter>> *>(VT_LAYER);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.Verify(name()) &&
           VerifyOffset(verifier, VT_INPUT) &&
           verifier.Verify(input()) &&
           verifier.VerifyVectorOfStrings(input()) &&
           VerifyOffset(verifier, VT_INPUT_SHAPE) &&
           verifier.Verify(input_shape()) &&
           verifier.VerifyVectorOfTables(input_shape()) &&
           VerifyOffset(verifier, VT_LAYER) &&
           verifier.Verify(layer()) &&
           verifier.VerifyVectorOfTables(layer()) &&
           verifier.EndTable();
  }
};

struct NetParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(NetParameter::VT_NAME, name);
  }
  void add_input(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> input) {
    fbb_.AddOffset(NetParameter::VT_INPUT, input);
  }
  void add_input_shape(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<BlobShape>>> input_shape) {
    fbb_.AddOffset(NetParameter::VT_INPUT_SHAPE, input_shape);
  }
  void add_layer(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<LayerParameter>>> layer) {
    fbb_.AddOffset(NetParameter::VT_LAYER, layer);
  }
  explicit NetParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  NetParameterBuilder &operator=(const NetParameterBuilder &);
  flatbuffers::Offset<NetParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<NetParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<NetParameter> CreateNetParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> input = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<BlobShape>>> input_shape = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<LayerParameter>>> layer = 0) {
  NetParameterBuilder builder_(_fbb);
  builder_.add_layer(layer);
  builder_.add_input_shape(input_shape);
  builder_.add_input(input);
  builder_.add_name(name);
  return builder_.Finish();
}

inline flatbuffers::Offset<NetParameter> CreateNetParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *name = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *input = nullptr,
    const std::vector<flatbuffers::Offset<BlobShape>> *input_shape = nullptr,
    const std::vector<flatbuffers::Offset<LayerParameter>> *layer = nullptr) {
  return feather::CreateNetParameter(
      _fbb,
      name ? _fbb.CreateString(name) : 0,
      input ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*input) : 0,
      input_shape ? _fbb.CreateVector<flatbuffers::Offset<BlobShape>>(*input_shape) : 0,
      layer ? _fbb.CreateVector<flatbuffers::Offset<LayerParameter>>(*layer) : 0);
}

struct InputParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NAME = 4,
    VT_DIM = 6
  };
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *name() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_NAME);
  }
  const flatbuffers::Vector<int64_t> *dim() const {
    return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_DIM);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.Verify(name()) &&
           verifier.VerifyVectorOfStrings(name()) &&
           VerifyOffset(verifier, VT_DIM) &&
           verifier.Verify(dim()) &&
           verifier.EndTable();
  }
};

struct InputParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> name) {
    fbb_.AddOffset(InputParameter::VT_NAME, name);
  }
  void add_dim(flatbuffers::Offset<flatbuffers::Vector<int64_t>> dim) {
    fbb_.AddOffset(InputParameter::VT_DIM, dim);
  }
  explicit InputParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  InputParameterBuilder &operator=(const InputParameterBuilder &);
  flatbuffers::Offset<InputParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<InputParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<InputParameter> CreateInputParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> name = 0,
    flatbuffers::Offset<flatbuffers::Vector<int64_t>> dim = 0) {
  InputParameterBuilder builder_(_fbb);
  builder_.add_dim(dim);
  builder_.add_name(name);
  return builder_.Finish();
}

inline flatbuffers::Offset<InputParameter> CreateInputParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *name = nullptr,
    const std::vector<int64_t> *dim = nullptr) {
  return feather::CreateInputParameter(
      _fbb,
      name ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*name) : 0,
      dim ? _fbb.CreateVector<int64_t>(*dim) : 0);
}

struct LayerParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NAME = 4,
    VT_TYPE = 6,
    VT_BOTTOM = 8,
    VT_TOP = 10,
    VT_BLOBS = 12,
    VT_INPUT_PARAM = 14,
    VT_ARGMAX_PARAM = 16,
    VT_BATCH_NORM_PARAM = 18,
    VT_BIAS_PARAM = 20,
    VT_CONCAT_PARAM = 22,
    VT_CONVOLUTION_PARAM = 24,
    VT_CROP_PARAM = 26,
    VT_DATA_PARAM = 28,
    VT_DROPOUT_PARAM = 30,
    VT_ELTWISE_PARAM = 32,
    VT_ELU_PARAM = 34,
    VT_EMBED_PARAM = 36,
    VT_EXP_PARAM = 38,
    VT_FLATTEN_PARAM = 40,
    VT_IMAGE_DATA_PARAM = 42,
    VT_INNER_PRODUCT_PARAM = 44,
    VT_LOG_PARAM = 46,
    VT_LRN_PARAM = 48,
    VT_POOLING_PARAM = 50,
    VT_POWER_PARAM = 52,
    VT_PRELU_PARAM = 54,
    VT_REDUCTION_PARAM = 56,
    VT_RELU_PARAM = 58,
    VT_RESHAPE_PARAM = 60,
    VT_SCALE_PARAM = 62,
    VT_SIGMOID_PARAM = 64,
    VT_SOFTMAX_PARAM = 66,
    VT_SLICE_PARAM = 68,
    VT_TANH_PARAM = 70
  };
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  const flatbuffers::String *type() const {
    return GetPointer<const flatbuffers::String *>(VT_TYPE);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *bottom() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_BOTTOM);
  }
  const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *top() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_TOP);
  }
  const flatbuffers::Vector<flatbuffers::Offset<BlobProto>> *blobs() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<BlobProto>> *>(VT_BLOBS);
  }
  const InputParameter *input_param() const {
    return GetPointer<const InputParameter *>(VT_INPUT_PARAM);
  }
  const ArgMaxParameter *argmax_param() const {
    return GetPointer<const ArgMaxParameter *>(VT_ARGMAX_PARAM);
  }
  const BatchNormParameter *batch_norm_param() const {
    return GetPointer<const BatchNormParameter *>(VT_BATCH_NORM_PARAM);
  }
  const BiasParameter *bias_param() const {
    return GetPointer<const BiasParameter *>(VT_BIAS_PARAM);
  }
  const ConcatParameter *concat_param() const {
    return GetPointer<const ConcatParameter *>(VT_CONCAT_PARAM);
  }
  const ConvolutionParameter *convolution_param() const {
    return GetPointer<const ConvolutionParameter *>(VT_CONVOLUTION_PARAM);
  }
  const CropParameter *crop_param() const {
    return GetPointer<const CropParameter *>(VT_CROP_PARAM);
  }
  const DataParameter *data_param() const {
    return GetPointer<const DataParameter *>(VT_DATA_PARAM);
  }
  const DropoutParameter *dropout_param() const {
    return GetPointer<const DropoutParameter *>(VT_DROPOUT_PARAM);
  }
  const EltwiseParameter *eltwise_param() const {
    return GetPointer<const EltwiseParameter *>(VT_ELTWISE_PARAM);
  }
  const ELUParameter *elu_param() const {
    return GetPointer<const ELUParameter *>(VT_ELU_PARAM);
  }
  const EmbedParameter *embed_param() const {
    return GetPointer<const EmbedParameter *>(VT_EMBED_PARAM);
  }
  const ExpParameter *exp_param() const {
    return GetPointer<const ExpParameter *>(VT_EXP_PARAM);
  }
  const FlattenParameter *flatten_param() const {
    return GetPointer<const FlattenParameter *>(VT_FLATTEN_PARAM);
  }
  const ImageDataParameter *image_data_param() const {
    return GetPointer<const ImageDataParameter *>(VT_IMAGE_DATA_PARAM);
  }
  const InnerProductParameter *inner_product_param() const {
    return GetPointer<const InnerProductParameter *>(VT_INNER_PRODUCT_PARAM);
  }
  const LogParameter *log_param() const {
    return GetPointer<const LogParameter *>(VT_LOG_PARAM);
  }
  const LRNParameter *lrn_param() const {
    return GetPointer<const LRNParameter *>(VT_LRN_PARAM);
  }
  const PoolingParameter *pooling_param() const {
    return GetPointer<const PoolingParameter *>(VT_POOLING_PARAM);
  }
  const PowerParameter *power_param() const {
    return GetPointer<const PowerParameter *>(VT_POWER_PARAM);
  }
  const PReLUParameter *prelu_param() const {
    return GetPointer<const PReLUParameter *>(VT_PRELU_PARAM);
  }
  const ReductionParameter *reduction_param() const {
    return GetPointer<const ReductionParameter *>(VT_REDUCTION_PARAM);
  }
  const ReLUParameter *relu_param() const {
    return GetPointer<const ReLUParameter *>(VT_RELU_PARAM);
  }
  const ReshapeParameter *reshape_param() const {
    return GetPointer<const ReshapeParameter *>(VT_RESHAPE_PARAM);
  }
  const ScaleParameter *scale_param() const {
    return GetPointer<const ScaleParameter *>(VT_SCALE_PARAM);
  }
  const SigmoidParameter *sigmoid_param() const {
    return GetPointer<const SigmoidParameter *>(VT_SIGMOID_PARAM);
  }
  const SoftmaxParameter *softmax_param() const {
    return GetPointer<const SoftmaxParameter *>(VT_SOFTMAX_PARAM);
  }
  const SliceParameter *slice_param() const {
    return GetPointer<const SliceParameter *>(VT_SLICE_PARAM);
  }
  const TanHParameter *tanh_param() const {
    return GetPointer<const TanHParameter *>(VT_TANH_PARAM);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_NAME) &&
           verifier.Verify(name()) &&
           VerifyOffset(verifier, VT_TYPE) &&
           verifier.Verify(type()) &&
           VerifyOffset(verifier, VT_BOTTOM) &&
           verifier.Verify(bottom()) &&
           verifier.VerifyVectorOfStrings(bottom()) &&
           VerifyOffset(verifier, VT_TOP) &&
           verifier.Verify(top()) &&
           verifier.VerifyVectorOfStrings(top()) &&
           VerifyOffset(verifier, VT_BLOBS) &&
           verifier.Verify(blobs()) &&
           verifier.VerifyVectorOfTables(blobs()) &&
           VerifyOffset(verifier, VT_INPUT_PARAM) &&
           verifier.VerifyTable(input_param()) &&
           VerifyOffset(verifier, VT_ARGMAX_PARAM) &&
           verifier.VerifyTable(argmax_param()) &&
           VerifyOffset(verifier, VT_BATCH_NORM_PARAM) &&
           verifier.VerifyTable(batch_norm_param()) &&
           VerifyOffset(verifier, VT_BIAS_PARAM) &&
           verifier.VerifyTable(bias_param()) &&
           VerifyOffset(verifier, VT_CONCAT_PARAM) &&
           verifier.VerifyTable(concat_param()) &&
           VerifyOffset(verifier, VT_CONVOLUTION_PARAM) &&
           verifier.VerifyTable(convolution_param()) &&
           VerifyOffset(verifier, VT_CROP_PARAM) &&
           verifier.VerifyTable(crop_param()) &&
           VerifyOffset(verifier, VT_DATA_PARAM) &&
           verifier.VerifyTable(data_param()) &&
           VerifyOffset(verifier, VT_DROPOUT_PARAM) &&
           verifier.VerifyTable(dropout_param()) &&
           VerifyOffset(verifier, VT_ELTWISE_PARAM) &&
           verifier.VerifyTable(eltwise_param()) &&
           VerifyOffset(verifier, VT_ELU_PARAM) &&
           verifier.VerifyTable(elu_param()) &&
           VerifyOffset(verifier, VT_EMBED_PARAM) &&
           verifier.VerifyTable(embed_param()) &&
           VerifyOffset(verifier, VT_EXP_PARAM) &&
           verifier.VerifyTable(exp_param()) &&
           VerifyOffset(verifier, VT_FLATTEN_PARAM) &&
           verifier.VerifyTable(flatten_param()) &&
           VerifyOffset(verifier, VT_IMAGE_DATA_PARAM) &&
           verifier.VerifyTable(image_data_param()) &&
           VerifyOffset(verifier, VT_INNER_PRODUCT_PARAM) &&
           verifier.VerifyTable(inner_product_param()) &&
           VerifyOffset(verifier, VT_LOG_PARAM) &&
           verifier.VerifyTable(log_param()) &&
           VerifyOffset(verifier, VT_LRN_PARAM) &&
           verifier.VerifyTable(lrn_param()) &&
           VerifyOffset(verifier, VT_POOLING_PARAM) &&
           verifier.VerifyTable(pooling_param()) &&
           VerifyOffset(verifier, VT_POWER_PARAM) &&
           verifier.VerifyTable(power_param()) &&
           VerifyOffset(verifier, VT_PRELU_PARAM) &&
           verifier.VerifyTable(prelu_param()) &&
           VerifyOffset(verifier, VT_REDUCTION_PARAM) &&
           verifier.VerifyTable(reduction_param()) &&
           VerifyOffset(verifier, VT_RELU_PARAM) &&
           verifier.VerifyTable(relu_param()) &&
           VerifyOffset(verifier, VT_RESHAPE_PARAM) &&
           verifier.VerifyTable(reshape_param()) &&
           VerifyOffset(verifier, VT_SCALE_PARAM) &&
           verifier.VerifyTable(scale_param()) &&
           VerifyOffset(verifier, VT_SIGMOID_PARAM) &&
           verifier.VerifyTable(sigmoid_param()) &&
           VerifyOffset(verifier, VT_SOFTMAX_PARAM) &&
           verifier.VerifyTable(softmax_param()) &&
           VerifyOffset(verifier, VT_SLICE_PARAM) &&
           verifier.VerifyTable(slice_param()) &&
           VerifyOffset(verifier, VT_TANH_PARAM) &&
           verifier.VerifyTable(tanh_param()) &&
           verifier.EndTable();
  }
};

struct LayerParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(LayerParameter::VT_NAME, name);
  }
  void add_type(flatbuffers::Offset<flatbuffers::String> type) {
    fbb_.AddOffset(LayerParameter::VT_TYPE, type);
  }
  void add_bottom(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> bottom) {
    fbb_.AddOffset(LayerParameter::VT_BOTTOM, bottom);
  }
  void add_top(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> top) {
    fbb_.AddOffset(LayerParameter::VT_TOP, top);
  }
  void add_blobs(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<BlobProto>>> blobs) {
    fbb_.AddOffset(LayerParameter::VT_BLOBS, blobs);
  }
  void add_input_param(flatbuffers::Offset<InputParameter> input_param) {
    fbb_.AddOffset(LayerParameter::VT_INPUT_PARAM, input_param);
  }
  void add_argmax_param(flatbuffers::Offset<ArgMaxParameter> argmax_param) {
    fbb_.AddOffset(LayerParameter::VT_ARGMAX_PARAM, argmax_param);
  }
  void add_batch_norm_param(flatbuffers::Offset<BatchNormParameter> batch_norm_param) {
    fbb_.AddOffset(LayerParameter::VT_BATCH_NORM_PARAM, batch_norm_param);
  }
  void add_bias_param(flatbuffers::Offset<BiasParameter> bias_param) {
    fbb_.AddOffset(LayerParameter::VT_BIAS_PARAM, bias_param);
  }
  void add_concat_param(flatbuffers::Offset<ConcatParameter> concat_param) {
    fbb_.AddOffset(LayerParameter::VT_CONCAT_PARAM, concat_param);
  }
  void add_convolution_param(flatbuffers::Offset<ConvolutionParameter> convolution_param) {
    fbb_.AddOffset(LayerParameter::VT_CONVOLUTION_PARAM, convolution_param);
  }
  void add_crop_param(flatbuffers::Offset<CropParameter> crop_param) {
    fbb_.AddOffset(LayerParameter::VT_CROP_PARAM, crop_param);
  }
  void add_data_param(flatbuffers::Offset<DataParameter> data_param) {
    fbb_.AddOffset(LayerParameter::VT_DATA_PARAM, data_param);
  }
  void add_dropout_param(flatbuffers::Offset<DropoutParameter> dropout_param) {
    fbb_.AddOffset(LayerParameter::VT_DROPOUT_PARAM, dropout_param);
  }
  void add_eltwise_param(flatbuffers::Offset<EltwiseParameter> eltwise_param) {
    fbb_.AddOffset(LayerParameter::VT_ELTWISE_PARAM, eltwise_param);
  }
  void add_elu_param(flatbuffers::Offset<ELUParameter> elu_param) {
    fbb_.AddOffset(LayerParameter::VT_ELU_PARAM, elu_param);
  }
  void add_embed_param(flatbuffers::Offset<EmbedParameter> embed_param) {
    fbb_.AddOffset(LayerParameter::VT_EMBED_PARAM, embed_param);
  }
  void add_exp_param(flatbuffers::Offset<ExpParameter> exp_param) {
    fbb_.AddOffset(LayerParameter::VT_EXP_PARAM, exp_param);
  }
  void add_flatten_param(flatbuffers::Offset<FlattenParameter> flatten_param) {
    fbb_.AddOffset(LayerParameter::VT_FLATTEN_PARAM, flatten_param);
  }
  void add_image_data_param(flatbuffers::Offset<ImageDataParameter> image_data_param) {
    fbb_.AddOffset(LayerParameter::VT_IMAGE_DATA_PARAM, image_data_param);
  }
  void add_inner_product_param(flatbuffers::Offset<InnerProductParameter> inner_product_param) {
    fbb_.AddOffset(LayerParameter::VT_INNER_PRODUCT_PARAM, inner_product_param);
  }
  void add_log_param(flatbuffers::Offset<LogParameter> log_param) {
    fbb_.AddOffset(LayerParameter::VT_LOG_PARAM, log_param);
  }
  void add_lrn_param(flatbuffers::Offset<LRNParameter> lrn_param) {
    fbb_.AddOffset(LayerParameter::VT_LRN_PARAM, lrn_param);
  }
  void add_pooling_param(flatbuffers::Offset<PoolingParameter> pooling_param) {
    fbb_.AddOffset(LayerParameter::VT_POOLING_PARAM, pooling_param);
  }
  void add_power_param(flatbuffers::Offset<PowerParameter> power_param) {
    fbb_.AddOffset(LayerParameter::VT_POWER_PARAM, power_param);
  }
  void add_prelu_param(flatbuffers::Offset<PReLUParameter> prelu_param) {
    fbb_.AddOffset(LayerParameter::VT_PRELU_PARAM, prelu_param);
  }
  void add_reduction_param(flatbuffers::Offset<ReductionParameter> reduction_param) {
    fbb_.AddOffset(LayerParameter::VT_REDUCTION_PARAM, reduction_param);
  }
  void add_relu_param(flatbuffers::Offset<ReLUParameter> relu_param) {
    fbb_.AddOffset(LayerParameter::VT_RELU_PARAM, relu_param);
  }
  void add_reshape_param(flatbuffers::Offset<ReshapeParameter> reshape_param) {
    fbb_.AddOffset(LayerParameter::VT_RESHAPE_PARAM, reshape_param);
  }
  void add_scale_param(flatbuffers::Offset<ScaleParameter> scale_param) {
    fbb_.AddOffset(LayerParameter::VT_SCALE_PARAM, scale_param);
  }
  void add_sigmoid_param(flatbuffers::Offset<SigmoidParameter> sigmoid_param) {
    fbb_.AddOffset(LayerParameter::VT_SIGMOID_PARAM, sigmoid_param);
  }
  void add_softmax_param(flatbuffers::Offset<SoftmaxParameter> softmax_param) {
    fbb_.AddOffset(LayerParameter::VT_SOFTMAX_PARAM, softmax_param);
  }
  void add_slice_param(flatbuffers::Offset<SliceParameter> slice_param) {
    fbb_.AddOffset(LayerParameter::VT_SLICE_PARAM, slice_param);
  }
  void add_tanh_param(flatbuffers::Offset<TanHParameter> tanh_param) {
    fbb_.AddOffset(LayerParameter::VT_TANH_PARAM, tanh_param);
  }
  explicit LayerParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LayerParameterBuilder &operator=(const LayerParameterBuilder &);
  flatbuffers::Offset<LayerParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LayerParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<LayerParameter> CreateLayerParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<flatbuffers::String> type = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> bottom = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> top = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<BlobProto>>> blobs = 0,
    flatbuffers::Offset<InputParameter> input_param = 0,
    flatbuffers::Offset<ArgMaxParameter> argmax_param = 0,
    flatbuffers::Offset<BatchNormParameter> batch_norm_param = 0,
    flatbuffers::Offset<BiasParameter> bias_param = 0,
    flatbuffers::Offset<ConcatParameter> concat_param = 0,
    flatbuffers::Offset<ConvolutionParameter> convolution_param = 0,
    flatbuffers::Offset<CropParameter> crop_param = 0,
    flatbuffers::Offset<DataParameter> data_param = 0,
    flatbuffers::Offset<DropoutParameter> dropout_param = 0,
    flatbuffers::Offset<EltwiseParameter> eltwise_param = 0,
    flatbuffers::Offset<ELUParameter> elu_param = 0,
    flatbuffers::Offset<EmbedParameter> embed_param = 0,
    flatbuffers::Offset<ExpParameter> exp_param = 0,
    flatbuffers::Offset<FlattenParameter> flatten_param = 0,
    flatbuffers::Offset<ImageDataParameter> image_data_param = 0,
    flatbuffers::Offset<InnerProductParameter> inner_product_param = 0,
    flatbuffers::Offset<LogParameter> log_param = 0,
    flatbuffers::Offset<LRNParameter> lrn_param = 0,
    flatbuffers::Offset<PoolingParameter> pooling_param = 0,
    flatbuffers::Offset<PowerParameter> power_param = 0,
    flatbuffers::Offset<PReLUParameter> prelu_param = 0,
    flatbuffers::Offset<ReductionParameter> reduction_param = 0,
    flatbuffers::Offset<ReLUParameter> relu_param = 0,
    flatbuffers::Offset<ReshapeParameter> reshape_param = 0,
    flatbuffers::Offset<ScaleParameter> scale_param = 0,
    flatbuffers::Offset<SigmoidParameter> sigmoid_param = 0,
    flatbuffers::Offset<SoftmaxParameter> softmax_param = 0,
    flatbuffers::Offset<SliceParameter> slice_param = 0,
    flatbuffers::Offset<TanHParameter> tanh_param = 0) {
  LayerParameterBuilder builder_(_fbb);
  builder_.add_tanh_param(tanh_param);
  builder_.add_slice_param(slice_param);
  builder_.add_softmax_param(softmax_param);
  builder_.add_sigmoid_param(sigmoid_param);
  builder_.add_scale_param(scale_param);
  builder_.add_reshape_param(reshape_param);
  builder_.add_relu_param(relu_param);
  builder_.add_reduction_param(reduction_param);
  builder_.add_prelu_param(prelu_param);
  builder_.add_power_param(power_param);
  builder_.add_pooling_param(pooling_param);
  builder_.add_lrn_param(lrn_param);
  builder_.add_log_param(log_param);
  builder_.add_inner_product_param(inner_product_param);
  builder_.add_image_data_param(image_data_param);
  builder_.add_flatten_param(flatten_param);
  builder_.add_exp_param(exp_param);
  builder_.add_embed_param(embed_param);
  builder_.add_elu_param(elu_param);
  builder_.add_eltwise_param(eltwise_param);
  builder_.add_dropout_param(dropout_param);
  builder_.add_data_param(data_param);
  builder_.add_crop_param(crop_param);
  builder_.add_convolution_param(convolution_param);
  builder_.add_concat_param(concat_param);
  builder_.add_bias_param(bias_param);
  builder_.add_batch_norm_param(batch_norm_param);
  builder_.add_argmax_param(argmax_param);
  builder_.add_input_param(input_param);
  builder_.add_blobs(blobs);
  builder_.add_top(top);
  builder_.add_bottom(bottom);
  builder_.add_type(type);
  builder_.add_name(name);
  return builder_.Finish();
}

inline flatbuffers::Offset<LayerParameter> CreateLayerParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *name = nullptr,
    const char *type = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *bottom = nullptr,
    const std::vector<flatbuffers::Offset<flatbuffers::String>> *top = nullptr,
    const std::vector<flatbuffers::Offset<BlobProto>> *blobs = nullptr,
    flatbuffers::Offset<InputParameter> input_param = 0,
    flatbuffers::Offset<ArgMaxParameter> argmax_param = 0,
    flatbuffers::Offset<BatchNormParameter> batch_norm_param = 0,
    flatbuffers::Offset<BiasParameter> bias_param = 0,
    flatbuffers::Offset<ConcatParameter> concat_param = 0,
    flatbuffers::Offset<ConvolutionParameter> convolution_param = 0,
    flatbuffers::Offset<CropParameter> crop_param = 0,
    flatbuffers::Offset<DataParameter> data_param = 0,
    flatbuffers::Offset<DropoutParameter> dropout_param = 0,
    flatbuffers::Offset<EltwiseParameter> eltwise_param = 0,
    flatbuffers::Offset<ELUParameter> elu_param = 0,
    flatbuffers::Offset<EmbedParameter> embed_param = 0,
    flatbuffers::Offset<ExpParameter> exp_param = 0,
    flatbuffers::Offset<FlattenParameter> flatten_param = 0,
    flatbuffers::Offset<ImageDataParameter> image_data_param = 0,
    flatbuffers::Offset<InnerProductParameter> inner_product_param = 0,
    flatbuffers::Offset<LogParameter> log_param = 0,
    flatbuffers::Offset<LRNParameter> lrn_param = 0,
    flatbuffers::Offset<PoolingParameter> pooling_param = 0,
    flatbuffers::Offset<PowerParameter> power_param = 0,
    flatbuffers::Offset<PReLUParameter> prelu_param = 0,
    flatbuffers::Offset<ReductionParameter> reduction_param = 0,
    flatbuffers::Offset<ReLUParameter> relu_param = 0,
    flatbuffers::Offset<ReshapeParameter> reshape_param = 0,
    flatbuffers::Offset<ScaleParameter> scale_param = 0,
    flatbuffers::Offset<SigmoidParameter> sigmoid_param = 0,
    flatbuffers::Offset<SoftmaxParameter> softmax_param = 0,
    flatbuffers::Offset<SliceParameter> slice_param = 0,
    flatbuffers::Offset<TanHParameter> tanh_param = 0) {
  return feather::CreateLayerParameter(
      _fbb,
      name ? _fbb.CreateString(name) : 0,
      type ? _fbb.CreateString(type) : 0,
      bottom ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*bottom) : 0,
      top ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*top) : 0,
      blobs ? _fbb.CreateVector<flatbuffers::Offset<BlobProto>>(*blobs) : 0,
      input_param,
      argmax_param,
      batch_norm_param,
      bias_param,
      concat_param,
      convolution_param,
      crop_param,
      data_param,
      dropout_param,
      eltwise_param,
      elu_param,
      embed_param,
      exp_param,
      flatten_param,
      image_data_param,
      inner_product_param,
      log_param,
      lrn_param,
      pooling_param,
      power_param,
      prelu_param,
      reduction_param,
      relu_param,
      reshape_param,
      scale_param,
      sigmoid_param,
      softmax_param,
      slice_param,
      tanh_param);
}

struct ArgMaxParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_OUT_MAX_VAL = 4,
    VT_TOP_K = 6,
    VT_AXIS = 8
  };
  bool out_max_val() const {
    return GetField<uint8_t>(VT_OUT_MAX_VAL, 0) != 0;
  }
  uint32_t top_k() const {
    return GetField<uint32_t>(VT_TOP_K, 1);
  }
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_OUT_MAX_VAL) &&
           VerifyField<uint32_t>(verifier, VT_TOP_K) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           verifier.EndTable();
  }
};

struct ArgMaxParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_out_max_val(bool out_max_val) {
    fbb_.AddElement<uint8_t>(ArgMaxParameter::VT_OUT_MAX_VAL, static_cast<uint8_t>(out_max_val), 0);
  }
  void add_top_k(uint32_t top_k) {
    fbb_.AddElement<uint32_t>(ArgMaxParameter::VT_TOP_K, top_k, 1);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(ArgMaxParameter::VT_AXIS, axis, 0);
  }
  explicit ArgMaxParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ArgMaxParameterBuilder &operator=(const ArgMaxParameterBuilder &);
  flatbuffers::Offset<ArgMaxParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ArgMaxParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ArgMaxParameter> CreateArgMaxParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool out_max_val = false,
    uint32_t top_k = 1,
    int32_t axis = 0) {
  ArgMaxParameterBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_top_k(top_k);
  builder_.add_out_max_val(out_max_val);
  return builder_.Finish();
}

struct ConcatParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_AXIS = 4,
    VT_CONCAT_DIM = 6
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  uint32_t concat_dim() const {
    return GetField<uint32_t>(VT_CONCAT_DIM, 1);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<uint32_t>(verifier, VT_CONCAT_DIM) &&
           verifier.EndTable();
  }
};

struct ConcatParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(ConcatParameter::VT_AXIS, axis, 1);
  }
  void add_concat_dim(uint32_t concat_dim) {
    fbb_.AddElement<uint32_t>(ConcatParameter::VT_CONCAT_DIM, concat_dim, 1);
  }
  explicit ConcatParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConcatParameterBuilder &operator=(const ConcatParameterBuilder &);
  flatbuffers::Offset<ConcatParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ConcatParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ConcatParameter> CreateConcatParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 1,
    uint32_t concat_dim = 1) {
  ConcatParameterBuilder builder_(_fbb);
  builder_.add_concat_dim(concat_dim);
  builder_.add_axis(axis);
  return builder_.Finish();
}

struct BatchNormParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_USE_GLOBAL_STATS = 4,
    VT_MOVING_AVERAGE_FRACTION = 6,
    VT_EPS = 8
  };
  bool use_global_stats() const {
    return GetField<uint8_t>(VT_USE_GLOBAL_STATS, 0) != 0;
  }
  float moving_average_fraction() const {
    return GetField<float>(VT_MOVING_AVERAGE_FRACTION, 0.999f);
  }
  float eps() const {
    return GetField<float>(VT_EPS, 1e-5f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_USE_GLOBAL_STATS) &&
           VerifyField<float>(verifier, VT_MOVING_AVERAGE_FRACTION) &&
           VerifyField<float>(verifier, VT_EPS) &&
           verifier.EndTable();
  }
};

struct BatchNormParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_use_global_stats(bool use_global_stats) {
    fbb_.AddElement<uint8_t>(BatchNormParameter::VT_USE_GLOBAL_STATS, static_cast<uint8_t>(use_global_stats), 0);
  }
  void add_moving_average_fraction(float moving_average_fraction) {
    fbb_.AddElement<float>(BatchNormParameter::VT_MOVING_AVERAGE_FRACTION, moving_average_fraction, 0.999f);
  }
  void add_eps(float eps) {
    fbb_.AddElement<float>(BatchNormParameter::VT_EPS, eps, 1e-5f);
  }
  explicit BatchNormParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BatchNormParameterBuilder &operator=(const BatchNormParameterBuilder &);
  flatbuffers::Offset<BatchNormParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BatchNormParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<BatchNormParameter> CreateBatchNormParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool use_global_stats = false,
    float moving_average_fraction = 0.999f,
    float eps = 1e-5f) {
  BatchNormParameterBuilder builder_(_fbb);
  builder_.add_eps(eps);
  builder_.add_moving_average_fraction(moving_average_fraction);
  builder_.add_use_global_stats(use_global_stats);
  return builder_.Finish();
}

struct BiasParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_AXIS = 4,
    VT_NUM_AXES = 6
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  int32_t num_axes() const {
    return GetField<int32_t>(VT_NUM_AXES, 1);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<int32_t>(verifier, VT_NUM_AXES) &&
           verifier.EndTable();
  }
};

struct BiasParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(BiasParameter::VT_AXIS, axis, 1);
  }
  void add_num_axes(int32_t num_axes) {
    fbb_.AddElement<int32_t>(BiasParameter::VT_NUM_AXES, num_axes, 1);
  }
  explicit BiasParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BiasParameterBuilder &operator=(const BiasParameterBuilder &);
  flatbuffers::Offset<BiasParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BiasParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<BiasParameter> CreateBiasParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 1,
    int32_t num_axes = 1) {
  BiasParameterBuilder builder_(_fbb);
  builder_.add_num_axes(num_axes);
  builder_.add_axis(axis);
  return builder_.Finish();
}

struct ConvolutionParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NUM_OUTPUT = 4,
    VT_BIAS_TERM = 6,
    VT_PAD = 8,
    VT_KERNEL_SIZE = 10,
    VT_STRIDE = 12,
    VT_DILATION = 14,
    VT_PAD_H = 16,
    VT_PAD_W = 18,
    VT_KERNEL_H = 20,
    VT_KERNEL_W = 22,
    VT_STRIDE_H = 24,
    VT_STRIDE_W = 26,
    VT_GROUP = 28,
    VT_AXIS = 30,
    VT_FORCE_ND_IM2COL = 32
  };
  uint32_t num_output() const {
    return GetField<uint32_t>(VT_NUM_OUTPUT, 0);
  }
  bool bias_term() const {
    return GetField<uint8_t>(VT_BIAS_TERM, 0) != 0;
  }
  const flatbuffers::Vector<uint32_t> *pad() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_PAD);
  }
  const flatbuffers::Vector<uint32_t> *kernel_size() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_KERNEL_SIZE);
  }
  const flatbuffers::Vector<uint32_t> *stride() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_STRIDE);
  }
  const flatbuffers::Vector<uint32_t> *dilation() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_DILATION);
  }
  uint32_t pad_h() const {
    return GetField<uint32_t>(VT_PAD_H, 0);
  }
  uint32_t pad_w() const {
    return GetField<uint32_t>(VT_PAD_W, 0);
  }
  uint32_t kernel_h() const {
    return GetField<uint32_t>(VT_KERNEL_H, 0);
  }
  uint32_t kernel_w() const {
    return GetField<uint32_t>(VT_KERNEL_W, 0);
  }
  uint32_t stride_h() const {
    return GetField<uint32_t>(VT_STRIDE_H, 0);
  }
  uint32_t stride_w() const {
    return GetField<uint32_t>(VT_STRIDE_W, 0);
  }
  uint32_t group() const {
    return GetField<uint32_t>(VT_GROUP, 1);
  }
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  bool force_nd_im2col() const {
    return GetField<uint8_t>(VT_FORCE_ND_IM2COL, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_NUM_OUTPUT) &&
           VerifyField<uint8_t>(verifier, VT_BIAS_TERM) &&
           VerifyOffset(verifier, VT_PAD) &&
           verifier.Verify(pad()) &&
           VerifyOffset(verifier, VT_KERNEL_SIZE) &&
           verifier.Verify(kernel_size()) &&
           VerifyOffset(verifier, VT_STRIDE) &&
           verifier.Verify(stride()) &&
           VerifyOffset(verifier, VT_DILATION) &&
           verifier.Verify(dilation()) &&
           VerifyField<uint32_t>(verifier, VT_PAD_H) &&
           VerifyField<uint32_t>(verifier, VT_PAD_W) &&
           VerifyField<uint32_t>(verifier, VT_KERNEL_H) &&
           VerifyField<uint32_t>(verifier, VT_KERNEL_W) &&
           VerifyField<uint32_t>(verifier, VT_STRIDE_H) &&
           VerifyField<uint32_t>(verifier, VT_STRIDE_W) &&
           VerifyField<uint32_t>(verifier, VT_GROUP) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<uint8_t>(verifier, VT_FORCE_ND_IM2COL) &&
           verifier.EndTable();
  }
};

struct ConvolutionParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_num_output(uint32_t num_output) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_NUM_OUTPUT, num_output, 0);
  }
  void add_bias_term(bool bias_term) {
    fbb_.AddElement<uint8_t>(ConvolutionParameter::VT_BIAS_TERM, static_cast<uint8_t>(bias_term), 0);
  }
  void add_pad(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> pad) {
    fbb_.AddOffset(ConvolutionParameter::VT_PAD, pad);
  }
  void add_kernel_size(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> kernel_size) {
    fbb_.AddOffset(ConvolutionParameter::VT_KERNEL_SIZE, kernel_size);
  }
  void add_stride(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> stride) {
    fbb_.AddOffset(ConvolutionParameter::VT_STRIDE, stride);
  }
  void add_dilation(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dilation) {
    fbb_.AddOffset(ConvolutionParameter::VT_DILATION, dilation);
  }
  void add_pad_h(uint32_t pad_h) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_PAD_H, pad_h, 0);
  }
  void add_pad_w(uint32_t pad_w) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_PAD_W, pad_w, 0);
  }
  void add_kernel_h(uint32_t kernel_h) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_KERNEL_H, kernel_h, 0);
  }
  void add_kernel_w(uint32_t kernel_w) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_KERNEL_W, kernel_w, 0);
  }
  void add_stride_h(uint32_t stride_h) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_STRIDE_H, stride_h, 0);
  }
  void add_stride_w(uint32_t stride_w) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_STRIDE_W, stride_w, 0);
  }
  void add_group(uint32_t group) {
    fbb_.AddElement<uint32_t>(ConvolutionParameter::VT_GROUP, group, 1);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(ConvolutionParameter::VT_AXIS, axis, 1);
  }
  void add_force_nd_im2col(bool force_nd_im2col) {
    fbb_.AddElement<uint8_t>(ConvolutionParameter::VT_FORCE_ND_IM2COL, static_cast<uint8_t>(force_nd_im2col), 0);
  }
  explicit ConvolutionParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ConvolutionParameterBuilder &operator=(const ConvolutionParameterBuilder &);
  flatbuffers::Offset<ConvolutionParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ConvolutionParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ConvolutionParameter> CreateConvolutionParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t num_output = 0,
    bool bias_term = false,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> pad = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> kernel_size = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> stride = 0,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> dilation = 0,
    uint32_t pad_h = 0,
    uint32_t pad_w = 0,
    uint32_t kernel_h = 0,
    uint32_t kernel_w = 0,
    uint32_t stride_h = 0,
    uint32_t stride_w = 0,
    uint32_t group = 1,
    int32_t axis = 1,
    bool force_nd_im2col = false) {
  ConvolutionParameterBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_group(group);
  builder_.add_stride_w(stride_w);
  builder_.add_stride_h(stride_h);
  builder_.add_kernel_w(kernel_w);
  builder_.add_kernel_h(kernel_h);
  builder_.add_pad_w(pad_w);
  builder_.add_pad_h(pad_h);
  builder_.add_dilation(dilation);
  builder_.add_stride(stride);
  builder_.add_kernel_size(kernel_size);
  builder_.add_pad(pad);
  builder_.add_num_output(num_output);
  builder_.add_force_nd_im2col(force_nd_im2col);
  builder_.add_bias_term(bias_term);
  return builder_.Finish();
}

inline flatbuffers::Offset<ConvolutionParameter> CreateConvolutionParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t num_output = 0,
    bool bias_term = false,
    const std::vector<uint32_t> *pad = nullptr,
    const std::vector<uint32_t> *kernel_size = nullptr,
    const std::vector<uint32_t> *stride = nullptr,
    const std::vector<uint32_t> *dilation = nullptr,
    uint32_t pad_h = 0,
    uint32_t pad_w = 0,
    uint32_t kernel_h = 0,
    uint32_t kernel_w = 0,
    uint32_t stride_h = 0,
    uint32_t stride_w = 0,
    uint32_t group = 1,
    int32_t axis = 1,
    bool force_nd_im2col = false) {
  return feather::CreateConvolutionParameter(
      _fbb,
      num_output,
      bias_term,
      pad ? _fbb.CreateVector<uint32_t>(*pad) : 0,
      kernel_size ? _fbb.CreateVector<uint32_t>(*kernel_size) : 0,
      stride ? _fbb.CreateVector<uint32_t>(*stride) : 0,
      dilation ? _fbb.CreateVector<uint32_t>(*dilation) : 0,
      pad_h,
      pad_w,
      kernel_h,
      kernel_w,
      stride_h,
      stride_w,
      group,
      axis,
      force_nd_im2col);
}

struct CropParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_AXIS = 4,
    VT_OFFSET = 6
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 2);
  }
  const flatbuffers::Vector<uint32_t> *offset() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_OFFSET);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyOffset(verifier, VT_OFFSET) &&
           verifier.Verify(offset()) &&
           verifier.EndTable();
  }
};

struct CropParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(CropParameter::VT_AXIS, axis, 2);
  }
  void add_offset(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> offset) {
    fbb_.AddOffset(CropParameter::VT_OFFSET, offset);
  }
  explicit CropParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  CropParameterBuilder &operator=(const CropParameterBuilder &);
  flatbuffers::Offset<CropParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<CropParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<CropParameter> CreateCropParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 2,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> offset = 0) {
  CropParameterBuilder builder_(_fbb);
  builder_.add_offset(offset);
  builder_.add_axis(axis);
  return builder_.Finish();
}

inline flatbuffers::Offset<CropParameter> CreateCropParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 2,
    const std::vector<uint32_t> *offset = nullptr) {
  return feather::CreateCropParameter(
      _fbb,
      axis,
      offset ? _fbb.CreateVector<uint32_t>(*offset) : 0);
}

struct DataParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_SOURCE = 4,
    VT_BATCH_SIZE = 6,
    VT_RAND_SKIP = 8,
    VT_SCALE = 10,
    VT_MEAN_FILE = 12,
    VT_CROP_SIZE = 14,
    VT_MIRROR = 16,
    VT_FORCE_ENCODED_COLOR = 18,
    VT_PREFETCH = 20
  };
  const flatbuffers::String *source() const {
    return GetPointer<const flatbuffers::String *>(VT_SOURCE);
  }
  uint32_t batch_size() const {
    return GetField<uint32_t>(VT_BATCH_SIZE, 0);
  }
  uint32_t rand_skip() const {
    return GetField<uint32_t>(VT_RAND_SKIP, 0);
  }
  float scale() const {
    return GetField<float>(VT_SCALE, 1.0f);
  }
  const flatbuffers::String *mean_file() const {
    return GetPointer<const flatbuffers::String *>(VT_MEAN_FILE);
  }
  uint32_t crop_size() const {
    return GetField<uint32_t>(VT_CROP_SIZE, 0);
  }
  bool mirror() const {
    return GetField<uint8_t>(VT_MIRROR, 0) != 0;
  }
  bool force_encoded_color() const {
    return GetField<uint8_t>(VT_FORCE_ENCODED_COLOR, 0) != 0;
  }
  uint32_t prefetch() const {
    return GetField<uint32_t>(VT_PREFETCH, 4);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_SOURCE) &&
           verifier.Verify(source()) &&
           VerifyField<uint32_t>(verifier, VT_BATCH_SIZE) &&
           VerifyField<uint32_t>(verifier, VT_RAND_SKIP) &&
           VerifyField<float>(verifier, VT_SCALE) &&
           VerifyOffset(verifier, VT_MEAN_FILE) &&
           verifier.Verify(mean_file()) &&
           VerifyField<uint32_t>(verifier, VT_CROP_SIZE) &&
           VerifyField<uint8_t>(verifier, VT_MIRROR) &&
           VerifyField<uint8_t>(verifier, VT_FORCE_ENCODED_COLOR) &&
           VerifyField<uint32_t>(verifier, VT_PREFETCH) &&
           verifier.EndTable();
  }
};

struct DataParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_source(flatbuffers::Offset<flatbuffers::String> source) {
    fbb_.AddOffset(DataParameter::VT_SOURCE, source);
  }
  void add_batch_size(uint32_t batch_size) {
    fbb_.AddElement<uint32_t>(DataParameter::VT_BATCH_SIZE, batch_size, 0);
  }
  void add_rand_skip(uint32_t rand_skip) {
    fbb_.AddElement<uint32_t>(DataParameter::VT_RAND_SKIP, rand_skip, 0);
  }
  void add_scale(float scale) {
    fbb_.AddElement<float>(DataParameter::VT_SCALE, scale, 1.0f);
  }
  void add_mean_file(flatbuffers::Offset<flatbuffers::String> mean_file) {
    fbb_.AddOffset(DataParameter::VT_MEAN_FILE, mean_file);
  }
  void add_crop_size(uint32_t crop_size) {
    fbb_.AddElement<uint32_t>(DataParameter::VT_CROP_SIZE, crop_size, 0);
  }
  void add_mirror(bool mirror) {
    fbb_.AddElement<uint8_t>(DataParameter::VT_MIRROR, static_cast<uint8_t>(mirror), 0);
  }
  void add_force_encoded_color(bool force_encoded_color) {
    fbb_.AddElement<uint8_t>(DataParameter::VT_FORCE_ENCODED_COLOR, static_cast<uint8_t>(force_encoded_color), 0);
  }
  void add_prefetch(uint32_t prefetch) {
    fbb_.AddElement<uint32_t>(DataParameter::VT_PREFETCH, prefetch, 4);
  }
  explicit DataParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DataParameterBuilder &operator=(const DataParameterBuilder &);
  flatbuffers::Offset<DataParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DataParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<DataParameter> CreateDataParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> source = 0,
    uint32_t batch_size = 0,
    uint32_t rand_skip = 0,
    float scale = 1.0f,
    flatbuffers::Offset<flatbuffers::String> mean_file = 0,
    uint32_t crop_size = 0,
    bool mirror = false,
    bool force_encoded_color = false,
    uint32_t prefetch = 4) {
  DataParameterBuilder builder_(_fbb);
  builder_.add_prefetch(prefetch);
  builder_.add_crop_size(crop_size);
  builder_.add_mean_file(mean_file);
  builder_.add_scale(scale);
  builder_.add_rand_skip(rand_skip);
  builder_.add_batch_size(batch_size);
  builder_.add_source(source);
  builder_.add_force_encoded_color(force_encoded_color);
  builder_.add_mirror(mirror);
  return builder_.Finish();
}

inline flatbuffers::Offset<DataParameter> CreateDataParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *source = nullptr,
    uint32_t batch_size = 0,
    uint32_t rand_skip = 0,
    float scale = 1.0f,
    const char *mean_file = nullptr,
    uint32_t crop_size = 0,
    bool mirror = false,
    bool force_encoded_color = false,
    uint32_t prefetch = 4) {
  return feather::CreateDataParameter(
      _fbb,
      source ? _fbb.CreateString(source) : 0,
      batch_size,
      rand_skip,
      scale,
      mean_file ? _fbb.CreateString(mean_file) : 0,
      crop_size,
      mirror,
      force_encoded_color,
      prefetch);
}

struct DropoutParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_DROPOUT_RATIO = 4
  };
  float dropout_ratio() const {
    return GetField<float>(VT_DROPOUT_RATIO, 0.5f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_DROPOUT_RATIO) &&
           verifier.EndTable();
  }
};

struct DropoutParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_dropout_ratio(float dropout_ratio) {
    fbb_.AddElement<float>(DropoutParameter::VT_DROPOUT_RATIO, dropout_ratio, 0.5f);
  }
  explicit DropoutParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  DropoutParameterBuilder &operator=(const DropoutParameterBuilder &);
  flatbuffers::Offset<DropoutParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<DropoutParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<DropoutParameter> CreateDropoutParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    float dropout_ratio = 0.5f) {
  DropoutParameterBuilder builder_(_fbb);
  builder_.add_dropout_ratio(dropout_ratio);
  return builder_.Finish();
}

struct EltwiseParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_OPERATION = 4,
    VT_COEFF = 6,
    VT_STABLE_PROD_GRAD = 8
  };
  feather::EltwiseParameter_::EltwiseOp operation() const {
    return static_cast<feather::EltwiseParameter_::EltwiseOp>(GetField<int32_t>(VT_OPERATION, 0));
  }
  const flatbuffers::Vector<float> *coeff() const {
    return GetPointer<const flatbuffers::Vector<float> *>(VT_COEFF);
  }
  bool stable_prod_grad() const {
    return GetField<uint8_t>(VT_STABLE_PROD_GRAD, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_OPERATION) &&
           VerifyOffset(verifier, VT_COEFF) &&
           verifier.Verify(coeff()) &&
           VerifyField<uint8_t>(verifier, VT_STABLE_PROD_GRAD) &&
           verifier.EndTable();
  }
};

struct EltwiseParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_operation(feather::EltwiseParameter_::EltwiseOp operation) {
    fbb_.AddElement<int32_t>(EltwiseParameter::VT_OPERATION, static_cast<int32_t>(operation), 0);
  }
  void add_coeff(flatbuffers::Offset<flatbuffers::Vector<float>> coeff) {
    fbb_.AddOffset(EltwiseParameter::VT_COEFF, coeff);
  }
  void add_stable_prod_grad(bool stable_prod_grad) {
    fbb_.AddElement<uint8_t>(EltwiseParameter::VT_STABLE_PROD_GRAD, static_cast<uint8_t>(stable_prod_grad), 0);
  }
  explicit EltwiseParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  EltwiseParameterBuilder &operator=(const EltwiseParameterBuilder &);
  flatbuffers::Offset<EltwiseParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<EltwiseParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<EltwiseParameter> CreateEltwiseParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    feather::EltwiseParameter_::EltwiseOp operation = feather::EltwiseParameter_::EltwiseOp_PROD,
    flatbuffers::Offset<flatbuffers::Vector<float>> coeff = 0,
    bool stable_prod_grad = false) {
  EltwiseParameterBuilder builder_(_fbb);
  builder_.add_coeff(coeff);
  builder_.add_operation(operation);
  builder_.add_stable_prod_grad(stable_prod_grad);
  return builder_.Finish();
}

inline flatbuffers::Offset<EltwiseParameter> CreateEltwiseParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    feather::EltwiseParameter_::EltwiseOp operation = feather::EltwiseParameter_::EltwiseOp_PROD,
    const std::vector<float> *coeff = nullptr,
    bool stable_prod_grad = false) {
  return feather::CreateEltwiseParameter(
      _fbb,
      operation,
      coeff ? _fbb.CreateVector<float>(*coeff) : 0,
      stable_prod_grad);
}

struct ELUParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_ALPHA = 4
  };
  float alpha() const {
    return GetField<float>(VT_ALPHA, 1.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_ALPHA) &&
           verifier.EndTable();
  }
};

struct ELUParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_alpha(float alpha) {
    fbb_.AddElement<float>(ELUParameter::VT_ALPHA, alpha, 1.0f);
  }
  explicit ELUParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ELUParameterBuilder &operator=(const ELUParameterBuilder &);
  flatbuffers::Offset<ELUParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ELUParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ELUParameter> CreateELUParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    float alpha = 1.0f) {
  ELUParameterBuilder builder_(_fbb);
  builder_.add_alpha(alpha);
  return builder_.Finish();
}

struct EmbedParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NUM_OUTPUT = 4,
    VT_INPUT_DIM = 6,
    VT_BIAS_TERM = 8
  };
  uint32_t num_output() const {
    return GetField<uint32_t>(VT_NUM_OUTPUT, 0);
  }
  uint32_t input_dim() const {
    return GetField<uint32_t>(VT_INPUT_DIM, 0);
  }
  bool bias_term() const {
    return GetField<uint8_t>(VT_BIAS_TERM, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_NUM_OUTPUT) &&
           VerifyField<uint32_t>(verifier, VT_INPUT_DIM) &&
           VerifyField<uint8_t>(verifier, VT_BIAS_TERM) &&
           verifier.EndTable();
  }
};

struct EmbedParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_num_output(uint32_t num_output) {
    fbb_.AddElement<uint32_t>(EmbedParameter::VT_NUM_OUTPUT, num_output, 0);
  }
  void add_input_dim(uint32_t input_dim) {
    fbb_.AddElement<uint32_t>(EmbedParameter::VT_INPUT_DIM, input_dim, 0);
  }
  void add_bias_term(bool bias_term) {
    fbb_.AddElement<uint8_t>(EmbedParameter::VT_BIAS_TERM, static_cast<uint8_t>(bias_term), 0);
  }
  explicit EmbedParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  EmbedParameterBuilder &operator=(const EmbedParameterBuilder &);
  flatbuffers::Offset<EmbedParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<EmbedParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<EmbedParameter> CreateEmbedParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t num_output = 0,
    uint32_t input_dim = 0,
    bool bias_term = false) {
  EmbedParameterBuilder builder_(_fbb);
  builder_.add_input_dim(input_dim);
  builder_.add_num_output(num_output);
  builder_.add_bias_term(bias_term);
  return builder_.Finish();
}

struct ExpParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_BASE = 4,
    VT_SCALE = 6,
    VT_SHIFT = 8
  };
  float base() const {
    return GetField<float>(VT_BASE, -1.0f);
  }
  float scale() const {
    return GetField<float>(VT_SCALE, 1.0f);
  }
  float shift() const {
    return GetField<float>(VT_SHIFT, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_BASE) &&
           VerifyField<float>(verifier, VT_SCALE) &&
           VerifyField<float>(verifier, VT_SHIFT) &&
           verifier.EndTable();
  }
};

struct ExpParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(float base) {
    fbb_.AddElement<float>(ExpParameter::VT_BASE, base, -1.0f);
  }
  void add_scale(float scale) {
    fbb_.AddElement<float>(ExpParameter::VT_SCALE, scale, 1.0f);
  }
  void add_shift(float shift) {
    fbb_.AddElement<float>(ExpParameter::VT_SHIFT, shift, 0.0f);
  }
  explicit ExpParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ExpParameterBuilder &operator=(const ExpParameterBuilder &);
  flatbuffers::Offset<ExpParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ExpParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ExpParameter> CreateExpParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    float base = -1.0f,
    float scale = 1.0f,
    float shift = 0.0f) {
  ExpParameterBuilder builder_(_fbb);
  builder_.add_shift(shift);
  builder_.add_scale(scale);
  builder_.add_base(base);
  return builder_.Finish();
}

/// Message that stores parameters used by FlattenLayer
struct FlattenParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_AXIS = 4,
    VT_END_AXIS = 6
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  int32_t end_axis() const {
    return GetField<int32_t>(VT_END_AXIS, -1);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<int32_t>(verifier, VT_END_AXIS) &&
           verifier.EndTable();
  }
};

struct FlattenParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(FlattenParameter::VT_AXIS, axis, 1);
  }
  void add_end_axis(int32_t end_axis) {
    fbb_.AddElement<int32_t>(FlattenParameter::VT_END_AXIS, end_axis, -1);
  }
  explicit FlattenParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FlattenParameterBuilder &operator=(const FlattenParameterBuilder &);
  flatbuffers::Offset<FlattenParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<FlattenParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<FlattenParameter> CreateFlattenParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 1,
    int32_t end_axis = -1) {
  FlattenParameterBuilder builder_(_fbb);
  builder_.add_end_axis(end_axis);
  builder_.add_axis(axis);
  return builder_.Finish();
}

struct ImageDataParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_SOURCE = 4,
    VT_BATCH_SIZE = 6,
    VT_RAND_SKIP = 8,
    VT_SHUFFLE = 10,
    VT_NEW_HEIGHT = 12,
    VT_NEW_WIDTH = 14,
    VT_IS_COLOR = 16,
    VT_SCALE = 18,
    VT_MEAN_FILE = 20,
    VT_CROP_SIZE = 22,
    VT_MIRROR = 24,
    VT_ROOT_FOLDER = 26
  };
  const flatbuffers::String *source() const {
    return GetPointer<const flatbuffers::String *>(VT_SOURCE);
  }
  uint32_t batch_size() const {
    return GetField<uint32_t>(VT_BATCH_SIZE, 1);
  }
  uint32_t rand_skip() const {
    return GetField<uint32_t>(VT_RAND_SKIP, 0);
  }
  bool shuffle() const {
    return GetField<uint8_t>(VT_SHUFFLE, 0) != 0;
  }
  uint32_t new_height() const {
    return GetField<uint32_t>(VT_NEW_HEIGHT, 0);
  }
  uint32_t new_width() const {
    return GetField<uint32_t>(VT_NEW_WIDTH, 0);
  }
  bool is_color() const {
    return GetField<uint8_t>(VT_IS_COLOR, 0) != 0;
  }
  float scale() const {
    return GetField<float>(VT_SCALE, 1.0f);
  }
  const flatbuffers::String *mean_file() const {
    return GetPointer<const flatbuffers::String *>(VT_MEAN_FILE);
  }
  uint32_t crop_size() const {
    return GetField<uint32_t>(VT_CROP_SIZE, 0);
  }
  bool mirror() const {
    return GetField<uint8_t>(VT_MIRROR, 0) != 0;
  }
  const flatbuffers::String *root_folder() const {
    return GetPointer<const flatbuffers::String *>(VT_ROOT_FOLDER);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_SOURCE) &&
           verifier.Verify(source()) &&
           VerifyField<uint32_t>(verifier, VT_BATCH_SIZE) &&
           VerifyField<uint32_t>(verifier, VT_RAND_SKIP) &&
           VerifyField<uint8_t>(verifier, VT_SHUFFLE) &&
           VerifyField<uint32_t>(verifier, VT_NEW_HEIGHT) &&
           VerifyField<uint32_t>(verifier, VT_NEW_WIDTH) &&
           VerifyField<uint8_t>(verifier, VT_IS_COLOR) &&
           VerifyField<float>(verifier, VT_SCALE) &&
           VerifyOffset(verifier, VT_MEAN_FILE) &&
           verifier.Verify(mean_file()) &&
           VerifyField<uint32_t>(verifier, VT_CROP_SIZE) &&
           VerifyField<uint8_t>(verifier, VT_MIRROR) &&
           VerifyOffset(verifier, VT_ROOT_FOLDER) &&
           verifier.Verify(root_folder()) &&
           verifier.EndTable();
  }
};

struct ImageDataParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_source(flatbuffers::Offset<flatbuffers::String> source) {
    fbb_.AddOffset(ImageDataParameter::VT_SOURCE, source);
  }
  void add_batch_size(uint32_t batch_size) {
    fbb_.AddElement<uint32_t>(ImageDataParameter::VT_BATCH_SIZE, batch_size, 1);
  }
  void add_rand_skip(uint32_t rand_skip) {
    fbb_.AddElement<uint32_t>(ImageDataParameter::VT_RAND_SKIP, rand_skip, 0);
  }
  void add_shuffle(bool shuffle) {
    fbb_.AddElement<uint8_t>(ImageDataParameter::VT_SHUFFLE, static_cast<uint8_t>(shuffle), 0);
  }
  void add_new_height(uint32_t new_height) {
    fbb_.AddElement<uint32_t>(ImageDataParameter::VT_NEW_HEIGHT, new_height, 0);
  }
  void add_new_width(uint32_t new_width) {
    fbb_.AddElement<uint32_t>(ImageDataParameter::VT_NEW_WIDTH, new_width, 0);
  }
  void add_is_color(bool is_color) {
    fbb_.AddElement<uint8_t>(ImageDataParameter::VT_IS_COLOR, static_cast<uint8_t>(is_color), 0);
  }
  void add_scale(float scale) {
    fbb_.AddElement<float>(ImageDataParameter::VT_SCALE, scale, 1.0f);
  }
  void add_mean_file(flatbuffers::Offset<flatbuffers::String> mean_file) {
    fbb_.AddOffset(ImageDataParameter::VT_MEAN_FILE, mean_file);
  }
  void add_crop_size(uint32_t crop_size) {
    fbb_.AddElement<uint32_t>(ImageDataParameter::VT_CROP_SIZE, crop_size, 0);
  }
  void add_mirror(bool mirror) {
    fbb_.AddElement<uint8_t>(ImageDataParameter::VT_MIRROR, static_cast<uint8_t>(mirror), 0);
  }
  void add_root_folder(flatbuffers::Offset<flatbuffers::String> root_folder) {
    fbb_.AddOffset(ImageDataParameter::VT_ROOT_FOLDER, root_folder);
  }
  explicit ImageDataParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ImageDataParameterBuilder &operator=(const ImageDataParameterBuilder &);
  flatbuffers::Offset<ImageDataParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ImageDataParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ImageDataParameter> CreateImageDataParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::String> source = 0,
    uint32_t batch_size = 1,
    uint32_t rand_skip = 0,
    bool shuffle = false,
    uint32_t new_height = 0,
    uint32_t new_width = 0,
    bool is_color = false,
    float scale = 1.0f,
    flatbuffers::Offset<flatbuffers::String> mean_file = 0,
    uint32_t crop_size = 0,
    bool mirror = false,
    flatbuffers::Offset<flatbuffers::String> root_folder = 0) {
  ImageDataParameterBuilder builder_(_fbb);
  builder_.add_root_folder(root_folder);
  builder_.add_crop_size(crop_size);
  builder_.add_mean_file(mean_file);
  builder_.add_scale(scale);
  builder_.add_new_width(new_width);
  builder_.add_new_height(new_height);
  builder_.add_rand_skip(rand_skip);
  builder_.add_batch_size(batch_size);
  builder_.add_source(source);
  builder_.add_mirror(mirror);
  builder_.add_is_color(is_color);
  builder_.add_shuffle(shuffle);
  return builder_.Finish();
}

inline flatbuffers::Offset<ImageDataParameter> CreateImageDataParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const char *source = nullptr,
    uint32_t batch_size = 1,
    uint32_t rand_skip = 0,
    bool shuffle = false,
    uint32_t new_height = 0,
    uint32_t new_width = 0,
    bool is_color = false,
    float scale = 1.0f,
    const char *mean_file = nullptr,
    uint32_t crop_size = 0,
    bool mirror = false,
    const char *root_folder = nullptr) {
  return feather::CreateImageDataParameter(
      _fbb,
      source ? _fbb.CreateString(source) : 0,
      batch_size,
      rand_skip,
      shuffle,
      new_height,
      new_width,
      is_color,
      scale,
      mean_file ? _fbb.CreateString(mean_file) : 0,
      crop_size,
      mirror,
      root_folder ? _fbb.CreateString(root_folder) : 0);
}

struct InnerProductParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NUM_OUTPUT = 4,
    VT_BIAS_TERM = 6,
    VT_AXIS = 8,
    VT_TRANSPOSE = 10
  };
  uint32_t num_output() const {
    return GetField<uint32_t>(VT_NUM_OUTPUT, 0);
  }
  bool bias_term() const {
    return GetField<uint8_t>(VT_BIAS_TERM, 0) != 0;
  }
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  bool transpose() const {
    return GetField<uint8_t>(VT_TRANSPOSE, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_NUM_OUTPUT) &&
           VerifyField<uint8_t>(verifier, VT_BIAS_TERM) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<uint8_t>(verifier, VT_TRANSPOSE) &&
           verifier.EndTable();
  }
};

struct InnerProductParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_num_output(uint32_t num_output) {
    fbb_.AddElement<uint32_t>(InnerProductParameter::VT_NUM_OUTPUT, num_output, 0);
  }
  void add_bias_term(bool bias_term) {
    fbb_.AddElement<uint8_t>(InnerProductParameter::VT_BIAS_TERM, static_cast<uint8_t>(bias_term), 0);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(InnerProductParameter::VT_AXIS, axis, 1);
  }
  void add_transpose(bool transpose) {
    fbb_.AddElement<uint8_t>(InnerProductParameter::VT_TRANSPOSE, static_cast<uint8_t>(transpose), 0);
  }
  explicit InnerProductParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  InnerProductParameterBuilder &operator=(const InnerProductParameterBuilder &);
  flatbuffers::Offset<InnerProductParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<InnerProductParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<InnerProductParameter> CreateInnerProductParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t num_output = 0,
    bool bias_term = false,
    int32_t axis = 1,
    bool transpose = false) {
  InnerProductParameterBuilder builder_(_fbb);
  builder_.add_axis(axis);
  builder_.add_num_output(num_output);
  builder_.add_transpose(transpose);
  builder_.add_bias_term(bias_term);
  return builder_.Finish();
}

struct LogParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_BASE = 4,
    VT_SCALE = 6,
    VT_SHIFT = 8
  };
  float base() const {
    return GetField<float>(VT_BASE, -1.0f);
  }
  float scale() const {
    return GetField<float>(VT_SCALE, 1.0f);
  }
  float shift() const {
    return GetField<float>(VT_SHIFT, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_BASE) &&
           VerifyField<float>(verifier, VT_SCALE) &&
           VerifyField<float>(verifier, VT_SHIFT) &&
           verifier.EndTable();
  }
};

struct LogParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_base(float base) {
    fbb_.AddElement<float>(LogParameter::VT_BASE, base, -1.0f);
  }
  void add_scale(float scale) {
    fbb_.AddElement<float>(LogParameter::VT_SCALE, scale, 1.0f);
  }
  void add_shift(float shift) {
    fbb_.AddElement<float>(LogParameter::VT_SHIFT, shift, 0.0f);
  }
  explicit LogParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LogParameterBuilder &operator=(const LogParameterBuilder &);
  flatbuffers::Offset<LogParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LogParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<LogParameter> CreateLogParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    float base = -1.0f,
    float scale = 1.0f,
    float shift = 0.0f) {
  LogParameterBuilder builder_(_fbb);
  builder_.add_shift(shift);
  builder_.add_scale(scale);
  builder_.add_base(base);
  return builder_.Finish();
}

struct LRNParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_LOCAL_SIZE = 4,
    VT_ALPHA = 6,
    VT_BETA = 8,
    VT_NORM_REGION = 10,
    VT_K = 12
  };
  uint32_t local_size() const {
    return GetField<uint32_t>(VT_LOCAL_SIZE, 5);
  }
  float alpha() const {
    return GetField<float>(VT_ALPHA, 1.f);
  }
  float beta() const {
    return GetField<float>(VT_BETA, 0.75f);
  }
  feather::LRNParameter_::NormRegion norm_region() const {
    return static_cast<feather::LRNParameter_::NormRegion>(GetField<int32_t>(VT_NORM_REGION, 0));
  }
  float k() const {
    return GetField<float>(VT_K, 1.f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_LOCAL_SIZE) &&
           VerifyField<float>(verifier, VT_ALPHA) &&
           VerifyField<float>(verifier, VT_BETA) &&
           VerifyField<int32_t>(verifier, VT_NORM_REGION) &&
           VerifyField<float>(verifier, VT_K) &&
           verifier.EndTable();
  }
};

struct LRNParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_local_size(uint32_t local_size) {
    fbb_.AddElement<uint32_t>(LRNParameter::VT_LOCAL_SIZE, local_size, 5);
  }
  void add_alpha(float alpha) {
    fbb_.AddElement<float>(LRNParameter::VT_ALPHA, alpha, 1.f);
  }
  void add_beta(float beta) {
    fbb_.AddElement<float>(LRNParameter::VT_BETA, beta, 0.75f);
  }
  void add_norm_region(feather::LRNParameter_::NormRegion norm_region) {
    fbb_.AddElement<int32_t>(LRNParameter::VT_NORM_REGION, static_cast<int32_t>(norm_region), 0);
  }
  void add_k(float k) {
    fbb_.AddElement<float>(LRNParameter::VT_K, k, 1.f);
  }
  explicit LRNParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LRNParameterBuilder &operator=(const LRNParameterBuilder &);
  flatbuffers::Offset<LRNParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LRNParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<LRNParameter> CreateLRNParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t local_size = 5,
    float alpha = 1.f,
    float beta = 0.75f,
    feather::LRNParameter_::NormRegion norm_region = feather::LRNParameter_::NormRegion_ACROSS_CHANNELS,
    float k = 1.f) {
  LRNParameterBuilder builder_(_fbb);
  builder_.add_k(k);
  builder_.add_norm_region(norm_region);
  builder_.add_beta(beta);
  builder_.add_alpha(alpha);
  builder_.add_local_size(local_size);
  return builder_.Finish();
}

struct PoolingParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_POOL = 4,
    VT_PAD_H = 6,
    VT_PAD_W = 8,
    VT_KERNEL_SIZE = 10,
    VT_KERNEL_H = 12,
    VT_KERNEL_W = 14,
    VT_STRIDE_H = 16,
    VT_STRIDE_W = 18,
    VT_GLOBAL_POOLING = 20
  };
  feather::PoolingParameter_::PoolMethod pool() const {
    return static_cast<feather::PoolingParameter_::PoolMethod>(GetField<int32_t>(VT_POOL, 0));
  }
  uint32_t pad_h() const {
    return GetField<uint32_t>(VT_PAD_H, 0);
  }
  uint32_t pad_w() const {
    return GetField<uint32_t>(VT_PAD_W, 0);
  }
  uint32_t kernel_size() const {
    return GetField<uint32_t>(VT_KERNEL_SIZE, 0);
  }
  uint32_t kernel_h() const {
    return GetField<uint32_t>(VT_KERNEL_H, 0);
  }
  uint32_t kernel_w() const {
    return GetField<uint32_t>(VT_KERNEL_W, 0);
  }
  uint32_t stride_h() const {
    return GetField<uint32_t>(VT_STRIDE_H, 0);
  }
  uint32_t stride_w() const {
    return GetField<uint32_t>(VT_STRIDE_W, 0);
  }
  bool global_pooling() const {
    return GetField<uint8_t>(VT_GLOBAL_POOLING, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_POOL) &&
           VerifyField<uint32_t>(verifier, VT_PAD_H) &&
           VerifyField<uint32_t>(verifier, VT_PAD_W) &&
           VerifyField<uint32_t>(verifier, VT_KERNEL_SIZE) &&
           VerifyField<uint32_t>(verifier, VT_KERNEL_H) &&
           VerifyField<uint32_t>(verifier, VT_KERNEL_W) &&
           VerifyField<uint32_t>(verifier, VT_STRIDE_H) &&
           VerifyField<uint32_t>(verifier, VT_STRIDE_W) &&
           VerifyField<uint8_t>(verifier, VT_GLOBAL_POOLING) &&
           verifier.EndTable();
  }
};

struct PoolingParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_pool(feather::PoolingParameter_::PoolMethod pool) {
    fbb_.AddElement<int32_t>(PoolingParameter::VT_POOL, static_cast<int32_t>(pool), 0);
  }
  void add_pad_h(uint32_t pad_h) {
    fbb_.AddElement<uint32_t>(PoolingParameter::VT_PAD_H, pad_h, 0);
  }
  void add_pad_w(uint32_t pad_w) {
    fbb_.AddElement<uint32_t>(PoolingParameter::VT_PAD_W, pad_w, 0);
  }
  void add_kernel_size(uint32_t kernel_size) {
    fbb_.AddElement<uint32_t>(PoolingParameter::VT_KERNEL_SIZE, kernel_size, 0);
  }
  void add_kernel_h(uint32_t kernel_h) {
    fbb_.AddElement<uint32_t>(PoolingParameter::VT_KERNEL_H, kernel_h, 0);
  }
  void add_kernel_w(uint32_t kernel_w) {
    fbb_.AddElement<uint32_t>(PoolingParameter::VT_KERNEL_W, kernel_w, 0);
  }
  void add_stride_h(uint32_t stride_h) {
    fbb_.AddElement<uint32_t>(PoolingParameter::VT_STRIDE_H, stride_h, 0);
  }
  void add_stride_w(uint32_t stride_w) {
    fbb_.AddElement<uint32_t>(PoolingParameter::VT_STRIDE_W, stride_w, 0);
  }
  void add_global_pooling(bool global_pooling) {
    fbb_.AddElement<uint8_t>(PoolingParameter::VT_GLOBAL_POOLING, static_cast<uint8_t>(global_pooling), 0);
  }
  explicit PoolingParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PoolingParameterBuilder &operator=(const PoolingParameterBuilder &);
  flatbuffers::Offset<PoolingParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PoolingParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<PoolingParameter> CreatePoolingParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    feather::PoolingParameter_::PoolMethod pool = feather::PoolingParameter_::PoolMethod_MAX_,
    uint32_t pad_h = 0,
    uint32_t pad_w = 0,
    uint32_t kernel_size = 0,
    uint32_t kernel_h = 0,
    uint32_t kernel_w = 0,
    uint32_t stride_h = 0,
    uint32_t stride_w = 0,
    bool global_pooling = false) {
  PoolingParameterBuilder builder_(_fbb);
  builder_.add_stride_w(stride_w);
  builder_.add_stride_h(stride_h);
  builder_.add_kernel_w(kernel_w);
  builder_.add_kernel_h(kernel_h);
  builder_.add_kernel_size(kernel_size);
  builder_.add_pad_w(pad_w);
  builder_.add_pad_h(pad_h);
  builder_.add_pool(pool);
  builder_.add_global_pooling(global_pooling);
  return builder_.Finish();
}

struct PowerParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_POWER = 4,
    VT_SCALE = 6,
    VT_SHIFT = 8
  };
  float power() const {
    return GetField<float>(VT_POWER, 1.0f);
  }
  float scale() const {
    return GetField<float>(VT_SCALE, 1.0f);
  }
  float shift() const {
    return GetField<float>(VT_SHIFT, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_POWER) &&
           VerifyField<float>(verifier, VT_SCALE) &&
           VerifyField<float>(verifier, VT_SHIFT) &&
           verifier.EndTable();
  }
};

struct PowerParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_power(float power) {
    fbb_.AddElement<float>(PowerParameter::VT_POWER, power, 1.0f);
  }
  void add_scale(float scale) {
    fbb_.AddElement<float>(PowerParameter::VT_SCALE, scale, 1.0f);
  }
  void add_shift(float shift) {
    fbb_.AddElement<float>(PowerParameter::VT_SHIFT, shift, 0.0f);
  }
  explicit PowerParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PowerParameterBuilder &operator=(const PowerParameterBuilder &);
  flatbuffers::Offset<PowerParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PowerParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<PowerParameter> CreatePowerParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    float power = 1.0f,
    float scale = 1.0f,
    float shift = 0.0f) {
  PowerParameterBuilder builder_(_fbb);
  builder_.add_shift(shift);
  builder_.add_scale(scale);
  builder_.add_power(power);
  return builder_.Finish();
}

struct PReLUParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_CHANNEL_SHARED = 4
  };
  bool channel_shared() const {
    return GetField<uint8_t>(VT_CHANNEL_SHARED, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_CHANNEL_SHARED) &&
           verifier.EndTable();
  }
};

struct PReLUParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_channel_shared(bool channel_shared) {
    fbb_.AddElement<uint8_t>(PReLUParameter::VT_CHANNEL_SHARED, static_cast<uint8_t>(channel_shared), 0);
  }
  explicit PReLUParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  PReLUParameterBuilder &operator=(const PReLUParameterBuilder &);
  flatbuffers::Offset<PReLUParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<PReLUParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<PReLUParameter> CreatePReLUParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    bool channel_shared = false) {
  PReLUParameterBuilder builder_(_fbb);
  builder_.add_channel_shared(channel_shared);
  return builder_.Finish();
}

struct RecurrentParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NUM_OUTPUT = 4,
    VT_DEBUG_INFO = 6,
    VT_EXPOSE_HIDDEN = 8
  };
  uint32_t num_output() const {
    return GetField<uint32_t>(VT_NUM_OUTPUT, 0);
  }
  bool debug_info() const {
    return GetField<uint8_t>(VT_DEBUG_INFO, 0) != 0;
  }
  bool expose_hidden() const {
    return GetField<uint8_t>(VT_EXPOSE_HIDDEN, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint32_t>(verifier, VT_NUM_OUTPUT) &&
           VerifyField<uint8_t>(verifier, VT_DEBUG_INFO) &&
           VerifyField<uint8_t>(verifier, VT_EXPOSE_HIDDEN) &&
           verifier.EndTable();
  }
};

struct RecurrentParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_num_output(uint32_t num_output) {
    fbb_.AddElement<uint32_t>(RecurrentParameter::VT_NUM_OUTPUT, num_output, 0);
  }
  void add_debug_info(bool debug_info) {
    fbb_.AddElement<uint8_t>(RecurrentParameter::VT_DEBUG_INFO, static_cast<uint8_t>(debug_info), 0);
  }
  void add_expose_hidden(bool expose_hidden) {
    fbb_.AddElement<uint8_t>(RecurrentParameter::VT_EXPOSE_HIDDEN, static_cast<uint8_t>(expose_hidden), 0);
  }
  explicit RecurrentParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RecurrentParameterBuilder &operator=(const RecurrentParameterBuilder &);
  flatbuffers::Offset<RecurrentParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<RecurrentParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<RecurrentParameter> CreateRecurrentParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint32_t num_output = 0,
    bool debug_info = false,
    bool expose_hidden = false) {
  RecurrentParameterBuilder builder_(_fbb);
  builder_.add_num_output(num_output);
  builder_.add_expose_hidden(expose_hidden);
  builder_.add_debug_info(debug_info);
  return builder_.Finish();
}

struct ReductionParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_OPERATION = 4,
    VT_AXIS = 6,
    VT_COEFF = 8
  };
  feather::ReductionParameter_::ReductionOp operation() const {
    return static_cast<feather::ReductionParameter_::ReductionOp>(GetField<int32_t>(VT_OPERATION, 0));
  }
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 0);
  }
  float coeff() const {
    return GetField<float>(VT_COEFF, 1.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_OPERATION) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<float>(verifier, VT_COEFF) &&
           verifier.EndTable();
  }
};

struct ReductionParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_operation(feather::ReductionParameter_::ReductionOp operation) {
    fbb_.AddElement<int32_t>(ReductionParameter::VT_OPERATION, static_cast<int32_t>(operation), 0);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(ReductionParameter::VT_AXIS, axis, 0);
  }
  void add_coeff(float coeff) {
    fbb_.AddElement<float>(ReductionParameter::VT_COEFF, coeff, 1.0f);
  }
  explicit ReductionParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReductionParameterBuilder &operator=(const ReductionParameterBuilder &);
  flatbuffers::Offset<ReductionParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReductionParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReductionParameter> CreateReductionParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    feather::ReductionParameter_::ReductionOp operation = static_cast<feather::ReductionParameter_::ReductionOp>(0),
    int32_t axis = 0,
    float coeff = 1.0f) {
  ReductionParameterBuilder builder_(_fbb);
  builder_.add_coeff(coeff);
  builder_.add_axis(axis);
  builder_.add_operation(operation);
  return builder_.Finish();
}

struct ReLUParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_NEGATIVE_SLOPE = 4
  };
  float negative_slope() const {
    return GetField<float>(VT_NEGATIVE_SLOPE, 0.0f);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<float>(verifier, VT_NEGATIVE_SLOPE) &&
           verifier.EndTable();
  }
};

struct ReLUParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_negative_slope(float negative_slope) {
    fbb_.AddElement<float>(ReLUParameter::VT_NEGATIVE_SLOPE, negative_slope, 0.0f);
  }
  explicit ReLUParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReLUParameterBuilder &operator=(const ReLUParameterBuilder &);
  flatbuffers::Offset<ReLUParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReLUParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReLUParameter> CreateReLUParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    float negative_slope = 0.0f) {
  ReLUParameterBuilder builder_(_fbb);
  builder_.add_negative_slope(negative_slope);
  return builder_.Finish();
}

struct ReshapeParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_SHAPE = 4,
    VT_AXIS = 6,
    VT_NUM_AXES = 8
  };
  const BlobShape *shape() const {
    return GetPointer<const BlobShape *>(VT_SHAPE);
  }
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 0);
  }
  int32_t num_axes() const {
    return GetField<int32_t>(VT_NUM_AXES, -1);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_SHAPE) &&
           verifier.VerifyTable(shape()) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<int32_t>(verifier, VT_NUM_AXES) &&
           verifier.EndTable();
  }
};

struct ReshapeParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_shape(flatbuffers::Offset<BlobShape> shape) {
    fbb_.AddOffset(ReshapeParameter::VT_SHAPE, shape);
  }
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(ReshapeParameter::VT_AXIS, axis, 0);
  }
  void add_num_axes(int32_t num_axes) {
    fbb_.AddElement<int32_t>(ReshapeParameter::VT_NUM_AXES, num_axes, -1);
  }
  explicit ReshapeParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ReshapeParameterBuilder &operator=(const ReshapeParameterBuilder &);
  flatbuffers::Offset<ReshapeParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ReshapeParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ReshapeParameter> CreateReshapeParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<BlobShape> shape = 0,
    int32_t axis = 0,
    int32_t num_axes = -1) {
  ReshapeParameterBuilder builder_(_fbb);
  builder_.add_num_axes(num_axes);
  builder_.add_axis(axis);
  builder_.add_shape(shape);
  return builder_.Finish();
}

struct TanHParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct TanHParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit TanHParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  TanHParameterBuilder &operator=(const TanHParameterBuilder &);
  flatbuffers::Offset<TanHParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<TanHParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<TanHParameter> CreateTanHParameter(
    flatbuffers::FlatBufferBuilder &_fbb) {
  TanHParameterBuilder builder_(_fbb);
  return builder_.Finish();
}

struct ScaleParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_AXIS = 4,
    VT_NUM_AXES = 6,
    VT_BIAS_TERM = 8
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  int32_t num_axes() const {
    return GetField<int32_t>(VT_NUM_AXES, 1);
  }
  bool bias_term() const {
    return GetField<uint8_t>(VT_BIAS_TERM, 0) != 0;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyField<int32_t>(verifier, VT_NUM_AXES) &&
           VerifyField<uint8_t>(verifier, VT_BIAS_TERM) &&
           verifier.EndTable();
  }
};

struct ScaleParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(ScaleParameter::VT_AXIS, axis, 1);
  }
  void add_num_axes(int32_t num_axes) {
    fbb_.AddElement<int32_t>(ScaleParameter::VT_NUM_AXES, num_axes, 1);
  }
  void add_bias_term(bool bias_term) {
    fbb_.AddElement<uint8_t>(ScaleParameter::VT_BIAS_TERM, static_cast<uint8_t>(bias_term), 0);
  }
  explicit ScaleParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ScaleParameterBuilder &operator=(const ScaleParameterBuilder &);
  flatbuffers::Offset<ScaleParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<ScaleParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<ScaleParameter> CreateScaleParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 1,
    int32_t num_axes = 1,
    bool bias_term = false) {
  ScaleParameterBuilder builder_(_fbb);
  builder_.add_num_axes(num_axes);
  builder_.add_axis(axis);
  builder_.add_bias_term(bias_term);
  return builder_.Finish();
}

struct SigmoidParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           verifier.EndTable();
  }
};

struct SigmoidParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  explicit SigmoidParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SigmoidParameterBuilder &operator=(const SigmoidParameterBuilder &);
  flatbuffers::Offset<SigmoidParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SigmoidParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<SigmoidParameter> CreateSigmoidParameter(
    flatbuffers::FlatBufferBuilder &_fbb) {
  SigmoidParameterBuilder builder_(_fbb);
  return builder_.Finish();
}

struct SliceParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_AXIS = 4,
    VT_SLICE_POINT = 6,
    VT_SLICE_DIM = 8
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  const flatbuffers::Vector<uint32_t> *slice_point() const {
    return GetPointer<const flatbuffers::Vector<uint32_t> *>(VT_SLICE_POINT);
  }
  uint32_t slice_dim() const {
    return GetField<uint32_t>(VT_SLICE_DIM, 1);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           VerifyOffset(verifier, VT_SLICE_POINT) &&
           verifier.Verify(slice_point()) &&
           VerifyField<uint32_t>(verifier, VT_SLICE_DIM) &&
           verifier.EndTable();
  }
};

struct SliceParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(SliceParameter::VT_AXIS, axis, 1);
  }
  void add_slice_point(flatbuffers::Offset<flatbuffers::Vector<uint32_t>> slice_point) {
    fbb_.AddOffset(SliceParameter::VT_SLICE_POINT, slice_point);
  }
  void add_slice_dim(uint32_t slice_dim) {
    fbb_.AddElement<uint32_t>(SliceParameter::VT_SLICE_DIM, slice_dim, 1);
  }
  explicit SliceParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SliceParameterBuilder &operator=(const SliceParameterBuilder &);
  flatbuffers::Offset<SliceParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SliceParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<SliceParameter> CreateSliceParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 1,
    flatbuffers::Offset<flatbuffers::Vector<uint32_t>> slice_point = 0,
    uint32_t slice_dim = 1) {
  SliceParameterBuilder builder_(_fbb);
  builder_.add_slice_dim(slice_dim);
  builder_.add_slice_point(slice_point);
  builder_.add_axis(axis);
  return builder_.Finish();
}

inline flatbuffers::Offset<SliceParameter> CreateSliceParameterDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 1,
    const std::vector<uint32_t> *slice_point = nullptr,
    uint32_t slice_dim = 1) {
  return feather::CreateSliceParameter(
      _fbb,
      axis,
      slice_point ? _fbb.CreateVector<uint32_t>(*slice_point) : 0,
      slice_dim);
}

struct SoftmaxParameter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_AXIS = 4
  };
  int32_t axis() const {
    return GetField<int32_t>(VT_AXIS, 1);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<int32_t>(verifier, VT_AXIS) &&
           verifier.EndTable();
  }
};

struct SoftmaxParameterBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_axis(int32_t axis) {
    fbb_.AddElement<int32_t>(SoftmaxParameter::VT_AXIS, axis, 1);
  }
  explicit SoftmaxParameterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SoftmaxParameterBuilder &operator=(const SoftmaxParameterBuilder &);
  flatbuffers::Offset<SoftmaxParameter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SoftmaxParameter>(end);
    return o;
  }
};

inline flatbuffers::Offset<SoftmaxParameter> CreateSoftmaxParameter(
    flatbuffers::FlatBufferBuilder &_fbb,
    int32_t axis = 1) {
  SoftmaxParameterBuilder builder_(_fbb);
  builder_.add_axis(axis);
  return builder_.Finish();
}

struct BlobShape FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_DIM = 4
  };
  const flatbuffers::Vector<int64_t> *dim() const {
    return GetPointer<const flatbuffers::Vector<int64_t> *>(VT_DIM);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DIM) &&
           verifier.Verify(dim()) &&
           verifier.EndTable();
  }
};

struct BlobShapeBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_dim(flatbuffers::Offset<flatbuffers::Vector<int64_t>> dim) {
    fbb_.AddOffset(BlobShape::VT_DIM, dim);
  }
  explicit BlobShapeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BlobShapeBuilder &operator=(const BlobShapeBuilder &);
  flatbuffers::Offset<BlobShape> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BlobShape>(end);
    return o;
  }
};

inline flatbuffers::Offset<BlobShape> CreateBlobShape(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<int64_t>> dim = 0) {
  BlobShapeBuilder builder_(_fbb);
  builder_.add_dim(dim);
  return builder_.Finish();
}

inline flatbuffers::Offset<BlobShape> CreateBlobShapeDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<int64_t> *dim = nullptr) {
  return feather::CreateBlobShape(
      _fbb,
      dim ? _fbb.CreateVector<int64_t>(*dim) : 0);
}

struct BlobProto FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  enum {
    VT_DATA = 4,
    VT_NUM = 6,
    VT_CHANNELS = 8,
    VT_HEIGHT = 10,
    VT_WIDTH = 12
  };
  const flatbuffers::Vector<float> *data() const {
    return GetPointer<const flatbuffers::Vector<float> *>(VT_DATA);
  }
  int32_t num() const {
    return GetField<int32_t>(VT_NUM, 0);
  }
  int32_t channels() const {
    return GetField<int32_t>(VT_CHANNELS, 0);
  }
  int32_t height() const {
    return GetField<int32_t>(VT_HEIGHT, 0);
  }
  int32_t width() const {
    return GetField<int32_t>(VT_WIDTH, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_DATA) &&
           verifier.Verify(data()) &&
           VerifyField<int32_t>(verifier, VT_NUM) &&
           VerifyField<int32_t>(verifier, VT_CHANNELS) &&
           VerifyField<int32_t>(verifier, VT_HEIGHT) &&
           VerifyField<int32_t>(verifier, VT_WIDTH) &&
           verifier.EndTable();
  }
};

struct BlobProtoBuilder {
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_data(flatbuffers::Offset<flatbuffers::Vector<float>> data) {
    fbb_.AddOffset(BlobProto::VT_DATA, data);
  }
  void add_num(int32_t num) {
    fbb_.AddElement<int32_t>(BlobProto::VT_NUM, num, 0);
  }
  void add_channels(int32_t channels) {
    fbb_.AddElement<int32_t>(BlobProto::VT_CHANNELS, channels, 0);
  }
  void add_height(int32_t height) {
    fbb_.AddElement<int32_t>(BlobProto::VT_HEIGHT, height, 0);
  }
  void add_width(int32_t width) {
    fbb_.AddElement<int32_t>(BlobProto::VT_WIDTH, width, 0);
  }
  explicit BlobProtoBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  BlobProtoBuilder &operator=(const BlobProtoBuilder &);
  flatbuffers::Offset<BlobProto> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<BlobProto>(end);
    return o;
  }
};

inline flatbuffers::Offset<BlobProto> CreateBlobProto(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<float>> data = 0,
    int32_t num = 0,
    int32_t channels = 0,
    int32_t height = 0,
    int32_t width = 0) {
  BlobProtoBuilder builder_(_fbb);
  builder_.add_width(width);
  builder_.add_height(height);
  builder_.add_channels(channels);
  builder_.add_num(num);
  builder_.add_data(data);
  return builder_.Finish();
}

inline flatbuffers::Offset<BlobProto> CreateBlobProtoDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<float> *data = nullptr,
    int32_t num = 0,
    int32_t channels = 0,
    int32_t height = 0,
    int32_t width = 0) {
  return feather::CreateBlobProto(
      _fbb,
      data ? _fbb.CreateVector<float>(*data) : 0,
      num,
      channels,
      height,
      width);
}

inline const feather::NetParameter *GetNetParameter(const void *buf) {
  return flatbuffers::GetRoot<feather::NetParameter>(buf);
}

inline bool VerifyNetParameterBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<feather::NetParameter>(nullptr);
}

inline void FinishNetParameterBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<feather::NetParameter> root) {
  fbb.Finish(root);
}

}  // namespace feather

#endif  // FLATBUFFERS_GENERATED_FEATHERSIMPLE_FEATHER_H_
